home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / dev / c / libiconv_src.lha / extras / locale_charset.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-07  |  28.3 KB  |  675 lines

  1.   /*
  2.    * This C function returns a canonical name for the character encoding
  3.    * used in the current locale. It returns NULL if it cannot be determined.
  4.    *
  5.    * This is an alternative to nl_langinfo(CODESET).
  6.    */
  7.  
  8.   #include <stddef.h>
  9.   #include <stdlib.h>
  10.   #include <string.h>
  11.  
  12.   #define streq(s1,s2) (!strcmp(s1,s2))
  13.  
  14.   const char* locale_charset = NULL;
  15.  
  16.   const char* get_locale_charset (void)
  17.     {
  18.       // When you call setlocale(LC_CTYPE,""), is examines the environment
  19.       // variables:
  20.       // 1. environment variable LC_ALL - an override for all LC_* variables,
  21.       // 2. environment variable LC_CTYPE,
  22.       // 3. environment variable LANG - a default for all LC_* variables.
  23.       const char * locale;
  24.       locale = getenv("LC_ALL");
  25.       if (!locale || !*locale) {
  26.         locale = getenv("LC_CTYPE");
  27.         if (!locale || !*locale)
  28.           locale = getenv("LANG");
  29.       }
  30.       // Determine locale_charset from the environment variables.
  31.       // Unfortunately there is no documented way of getting the character set
  32.       // that was specified as part of the LC_CTYPE category. We have to parse
  33.       // the environment variables ourselves.
  34.       // Recall that a locale specification has the form
  35.       //   language_COUNTRY.charset
  36.       // but there are also aliases. Here is the union of what I found in
  37.       // /usr/X11R6/lib/X11/locale/locale.alias (X11R6) and
  38.       // /usr/share/locale/locale.alias (GNU libc2).
  39.       //
  40.       // X11R6 locale.alias:
  41.       //   POSIX                   C
  42.       //   POSIX-UTF2              C
  43.       //   C_C.C                   C
  44.       //   C.en                    C
  45.       //   C.iso88591              en_US.ISO8859-1
  46.       //   Cextend                 en_US.ISO8859-1
  47.       //   Cextend.en              en_US.ISO8859-1
  48.       //   English_United-States.437       C
  49.       //   #
  50.       //   ar                      ar_AA.ISO8859-6
  51.       //   ar_AA                   ar_AA.ISO8859-6
  52.       //   ar_AA.ISO_8859-6        ar_AA.ISO8859-6
  53.       //   ar_SA.iso88596          ar_AA.ISO8859-6
  54.       //   bg                      bg_BG.ISO8859-5
  55.       //   bg_BG                   bg_BG.ISO8859-5
  56.       //   bg_BG.ISO_8859-5        bg_BG.ISO8859-5
  57.       //   bg_BG.iso88595          bg_BG.ISO8859-5
  58.       //   cs                      cs_CZ.ISO8859-2
  59.       //   cs_CS                   cs_CZ.ISO8859-2
  60.       //   cs_CS.ISO8859-2         cs_CZ.ISO8859-2
  61.       //   cs_CS.ISO_8859-2        cs_CZ.ISO8859-2
  62.       //   cs_CZ.iso88592          cs_CZ.ISO8859-2
  63.       //   cz                      cz_CZ.ISO8859-2
  64.       //   cz_CZ                   cz_CZ.ISO8859-2
  65.       //   cs_CZ.ISO_8859-2        cs_CZ.ISO8859-2
  66.       //   da                      da_DK.ISO8859-1
  67.       //   da_DK                   da_DK.ISO8859-1
  68.       //   da_DK.88591             da_DK.ISO8859-1
  69.       //   da_DK.88591.en          da_DK.ISO8859-1
  70.       //   da_DK.iso88591          da_DK.ISO8859-1
  71.       //   da_DK.ISO_8859-1        da_DK.ISO8859-1
  72.       //   de                      de_DE.ISO8859-1
  73.       //   de_AT                   de_AT.ISO8859-1
  74.       //   de_AT.ISO_8859-1        de_AT.ISO8859-1
  75.       //   de_CH                   de_CH.ISO8859-1
  76.       //   de_CH.ISO_8859-1        de_CH.ISO8859-1
  77.       //   de_DE                   de_DE.ISO8859-1
  78.       //   de_DE.88591             de_DE.ISO8859-1
  79.       //   de_DE.88591.en          de_DE.ISO8859-1
  80.       //   de_DE.iso88591          de_DE.ISO8859-1
  81.       //   de_DE.ISO_8859-1        de_DE.ISO8859-1
  82.       //   GER_DE.8859             de_DE.ISO8859-1
  83.       //   GER_DE.8859.in          de_DE.ISO8859-1
  84.       //   el                      el_GR.ISO8859-7
  85.       //   el_GR                   el_GR.ISO8859-7
  86.       //   el_GR.iso88597          el_GR.ISO8859-7
  87.       //   el_GR.ISO_8859-7        el_GR.ISO8859-7
  88.       //   en                      en_US.ISO8859-1
  89.       //   en_AU                   en_AU.ISO8859-1
  90.       //   en_AU.ISO_8859-1        en_AU.ISO8859-1
  91.       //   en_CA                   en_CA.ISO8859-1
  92.       //   en_CA.ISO_8859-1        en_CA.ISO8859-1
  93.       //   en_GB                   en_GB.ISO8859-1
  94.       //   en_GB.88591             en_GB.ISO8859-1
  95.       //   en_GB.88591.en          en_GB.ISO8859-1
  96.       //   en_GB.iso88591          en_GB.ISO8859-1
  97.       //   en_GB.ISO_8859-1        en_GB.ISO8859-1
  98.       //   en_UK                   en_GB.ISO8859-1
  99.       //   ENG_GB.8859             en_GB.ISO8859-1
  100.       //   ENG_GB.8859.in          en_GB.ISO8859-1
  101.       //   en_IE                   en_IE.ISO8859-1
  102.       //   en_NZ                   en_NZ.ISO8859-1
  103.       //   en_US                   en_US.ISO8859-1
  104.       //   en_US.88591             en_US.ISO8859-1
  105.       //   en_US.88591.en          en_US.ISO8859-1
  106.       //   en_US.iso88591          en_US.ISO8859-1
  107.       //   en_US.ISO_8859-1        en_US.ISO8859-1
  108.       //   es                      es_ES.ISO8859-1
  109.       //   es_AR                   es_AR.ISO8859-1
  110.       //   es_BO                   es_BO.ISO8859-1
  111.       //   es_CL                   es_CL.ISO8859-1
  112.       //   es_CO                   es_CO.ISO8859-1
  113.       //   es_CR                   es_CR.ISO8859-1
  114.       //   es_EC                   es_EC.ISO8859-1
  115.       //   es_ES                   es_ES.ISO8859-1
  116.       //   es_ES.88591             es_ES.ISO8859-1
  117.       //   es_ES.88591.en          es_ES.ISO8859-1
  118.       //   es_ES.iso88591          es_ES.ISO8859-1
  119.       //   es_ES.ISO_8859-1        es_ES.ISO8859-1
  120.       //   es_GT                   es_GT.ISO8859-1
  121.       //   es_MX                   es_MX.ISO8859-1
  122.       //   es_NI                   es_NI.ISO8859-1
  123.       //   es_PA                   es_PA.ISO8859-1
  124.       //   es_PE                   es_PE.ISO8859-1
  125.       //   es_PY                   es_PY.ISO8859-1
  126.       //   es_SV                   es_SV.ISO8859-1
  127.       //   es_UY                   es_UY.ISO8859-1
  128.       //   es_VE                   es_VE.ISO8859-1
  129.       //   fi                      fi_FI.ISO8859-1
  130.       //   fi_FI                   fi_FI.ISO8859-1
  131.       //   fi_FI.88591             fi_FI.ISO8859-1
  132.       //   fi_FI.88591.en          fi_FI.ISO8859-1
  133.       //   fi_FI.iso88591          fi_FI.ISO8859-1
  134.       //   fi_FI.ISO_8859-1        fi_FI.ISO8859-1
  135.       //   fr                      fr_FR.ISO8859-1
  136.       //   fr_BE                   fr_BE.ISO8859-1
  137.       //   fr_BE.88591             fr_BE.ISO8859-1
  138.       //   fr_BE.88591.en          fr_BE.ISO8859-1
  139.       //   fr_BE.ISO_8859-1        fr_BE.ISO8859-1
  140.       //   fr_CA                   fr_CA.ISO8859-1
  141.       //   fr_CA.88591             fr_CA.ISO8859-1
  142.       //   fr_CA.88591.en          fr_CA.ISO8859-1
  143.       //   fr_CA.iso88591          fr_CA.ISO8859-1
  144.       //   fr_CA.ISO_8859-1        fr_CA.ISO8859-1
  145.       //   fr_CH                   fr_CH.ISO8859-1
  146.       //   fr_CH.88591             fr_CH.ISO8859-1
  147.       //   fr_CH.88591.en          fr_CH.ISO8859-1
  148.       //   fr_CH.ISO_8859-1        fr_CH.ISO8859-1
  149.       //   fr_FR                   fr_FR.ISO8859-1
  150.       //   fr_FR.88591             fr_FR.ISO8859-1
  151.       //   fr_FR.88591.en          fr_FR.ISO8859-1
  152.       //   fr_FR.iso88591          fr_FR.ISO8859-1
  153.       //   fr_FR.ISO_8859-1        fr_FR.ISO8859-1
  154.       //   FRE_FR.8859             fr_FR.ISO8859-1
  155.       //   FRE_FR.8859.in          fr_FR.ISO8859-1
  156.       //   he                      he_IL.ISO8859-8
  157.       //   he_IL                   he_IL.ISO8859-8
  158.       //   he_IL.iso88598          he_IL.ISO8859-8
  159.       //   hr                      hr_HR.ISO8859-2
  160.       //   hr_HR                   hr_HR.ISO8859-2
  161.       //   hr_HR.iso88592          hr_HR.ISO8859-2
  162.       //   hr_HR.ISO_8859-2        hr_HR.ISO8859-2
  163.       //   hu                      hu_HU.ISO8859-2
  164.       //   hu_HU                   hu_HU.ISO8859-2
  165.       //   hu_HU.iso88592          hu_HU.ISO8859-2
  166.       //   hu_HU.ISO_8859-2        hu_HU.ISO8859-2
  167.       //   is                      is_IS.ISO8859-1
  168.       //   is_IS                   is_IS.ISO8859-1
  169.       //   is_IS.iso88591          is_IS.ISO8859-1
  170.       //   is_IS.ISO_8859-1        is_IS.ISO8859-1
  171.       //   it                      it_IT.ISO8859-1
  172.       //   it_CH                   it_CH.ISO8859-1
  173.       //   it_CH.ISO_8859-1        it_CH.ISO8859-1
  174.       //   it_IT                   it_IT.ISO8859-1
  175.       //   it_IT.88591             it_IT.ISO8859-1
  176.       //   it_IT.88591.en          it_IT.ISO8859-1
  177.       //   it_IT.iso88591          it_IT.ISO8859-1
  178.       //   it_IT.ISO_8859-1        it_IT.ISO8859-1
  179.       //   iw                      iw_IL.ISO8859-8
  180.       //   iw_IL                   iw_IL.ISO8859-8
  181.       //   iw_IL.iso88598          iw_IL.ISO8859-8
  182.       //   iw_IL.ISO_8859-8        iw_IL.ISO8859-8
  183.       //   ja                      ja_JP.eucJP
  184.       //   ja_JP                   ja_JP.eucJP
  185.       //   ja_JP.ujis              ja_JP.eucJP
  186.       //   ja_JP.eucJP             ja_JP.eucJP
  187.       //   Jp_JP                   ja_JP.eucJP
  188.       //   ja_JP.AJEC              ja_JP.eucJP
  189.       //   ja_JP.EUC               ja_JP.eucJP
  190.       //   ja_JP.ISO-2022-JP       ja_JP.JIS7
  191.       //   ja_JP.JIS               ja_JP.JIS7
  192.       //   ja_JP.jis7              ja_JP.JIS7
  193.       //   ja_JP.mscode            ja_JP.SJIS
  194.       //   ja_JP.SJIS              ja_JP.SJIS
  195.       //   ko                      ko_KR.eucKR
  196.       //   ko_KR                   ko_KR.eucKR
  197.       //   ko_KR.EUC               ko_KR.eucKR
  198.       //   ko_KR.euc               ko_KR.eucKR
  199.       //   # most locales in FreeBSD 2.1.[56] do not work, allow use of generic latin-1
  200.       //   lt_LN.ISO_8859-1        lt_LN.ISO8859-1
  201.       //   mk                      mk_MK.ISO8859-5
  202.       //   mk_MK                   mk_MK.ISO8859-5
  203.       //   mk_MK.ISO_8859-5        mk_MK.ISO8859-5
  204.       //   nl                      nl_NL.ISO8859-1
  205.       //   nl_BE                   nl_BE.ISO8859-1
  206.       //   nl_BE.88591             nl_BE.ISO8859-1
  207.       //   nl_BE.88591.en          nl_BE.ISO8859-1
  208.       //   nl_BE.ISO_8859-1        nl_BE.ISO8859-1
  209.       //   nl_NL                   nl_NL.ISO8859-1
  210.       //   nl_NL.88591             nl_NL.ISO8859-1
  211.       //   nl_NL.88591.en          nl_NL.ISO8859-1
  212.       //   nl_NL.iso88591          nl_NL.ISO8859-1
  213.       //   nl_NL.ISO_8859-1        nl_NL.ISO8859-1
  214.       //   no                      no_NO.ISO8859-1
  215.       //   no_NO                   no_NO.ISO8859-1
  216.       //   no_NO.88591             no_NO.ISO8859-1
  217.       //   no_NO.88591.en          no_NO.ISO8859-1
  218.       //   no_NO.iso88591          no_NO.ISO8859-1
  219.       //   no_NO.ISO_8859-1        no_NO.ISO8859-1
  220.       //   pl                      pl_PL.ISO8859-2
  221.       //   pl_PL                   pl_PL.ISO8859-2
  222.       //   pl_PL.iso88592          pl_PL.ISO8859-2
  223.       //   pl_PL.ISO_8859-2        pl_PL.ISO8859-2
  224.       //   pt                      pt_PT.ISO8859-1
  225.       //   pt_BR                   pt_BR.ISO8859-1
  226.       //   pt_PT                   pt_PT.ISO8859-1
  227.       //   pt_PT.88591             pt_PT.ISO8859-1
  228.       //   pt_PT.88591.en          pt_PT.ISO8859-1
  229.       //   pt_PT.iso88591          pt_PT.ISO8859-1
  230.       //   pt_PT.ISO_8859-1        pt_PT.ISO8859-1
  231.       //   ro                      ro_RO.ISO8859-2
  232.       //   ro_RO                   ro_RO.ISO8859-2
  233.       //   ro_RO.iso88592          ro_RO.ISO8859-2
  234.       //   ro_RO.ISO_8859-2        ro_RO.ISO8859-2
  235.       //   ru                      ru_RU.ISO8859-5
  236.       //   ru_RU                   ru_RU.ISO8859-5
  237.       //   ru_RU.iso88595          ru_RU.ISO8859-5
  238.       //   ru_RU.ISO_8859-5        ru_RU.ISO8859-5
  239.       //   ru_SU                   ru_RU.ISO8859-5
  240.       //   ru_SU.ISO8859-5         ru_RU.ISO8859-5
  241.       //   ru_SU.ISO_8859-5        ru_RU.ISO8859-5
  242.       //   ru_SU.KOI8-R            ru_RU.KOI8-R
  243.       //   sh                      sh_YU.ISO8859-2
  244.       //   sh_YU                   sh_YU.ISO8859-2
  245.       //   sh_YU.ISO_8859-2        sh_YU.ISO8859-2
  246.       //   sh_SP                   sh_YU.ISO8859-2
  247.       //   sk                      sk_SK.ISO8859-2
  248.       //   sk_SK                   sk_SK.ISO8859-2
  249.       //   sk_SK.ISO_8859-2        sk_SK.ISO8859-2
  250.       //   sl                      sl_CS.ISO8859-2
  251.       //   sl_CS                   sl_CS.ISO8859-2
  252.       //   sl_CS.ISO_8859-2        sl_CS.ISO8859-2
  253.       //   sl_SI                   sl_SI.ISO8859-2
  254.       //   sl_SI.iso88592          sl_SI.ISO8859-2
  255.       //   sl_SI.ISO_8859-2        sl_SI.ISO8859-2
  256.       //   sp                      sp_YU.ISO8859-5
  257.       //   sp_YU                   sp_YU.ISO8859-5
  258.       //   sp_YU.ISO_8859-5        sp_YU.ISO8859-5
  259.       //   sr_SP                   sr_SP.ISO8859-2
  260.       //   sr_SP.ISO_8859-2        sr_SP.ISO8859-2
  261.       //   sv                      sv_SE.ISO8859-1
  262.       //   sv_SE                   sv_SE.ISO8859-1
  263.       //   sv_SE.88591             sv_SE.ISO8859-1
  264.       //   sv_SE.88591.en          sv_SE.ISO8859-1
  265.       //   sv_SE.iso88591          sv_SE.ISO8859-1
  266.       //   sv_SE.ISO_8859-1        sv_SE.ISO8859-1
  267.       //   th_TH                   th_TH.TACTIS
  268.       //   tr                      tr_TR.ISO8859-9
  269.       //   tr_TR                   tr_TR.ISO8859-9
  270.       //   tr_TR.iso88599          tr_TR.ISO8859-9
  271.       //   tr_TR.ISO_8859-9        tr_TR.ISO8859-9
  272.       //   zh                      zh_CN.eucCN
  273.       //   zh_CN                   zh_CN.eucCN
  274.       //   zh_CN.EUC               zh_CN.eucCN
  275.       //   zh_TW                   zh_TW.eucTW
  276.       //   zh_TW.EUC               zh_TW.eucTW
  277.       //   # The following locale names are used in SCO 3.0
  278.       //   english_uk.8859         en_GB.ISO8859-1
  279.       //   english_us.8859         en_US.ISO8859-1
  280.       //   english_us.ascii        en_US.ISO8859-1
  281.       //   french_france.8859      fr_FR.ISO8859-1
  282.       //   german_germany.8859     de_DE.ISO8859-1
  283.       //   portuguese_brazil.8859  pt_BR.ISO8859-1
  284.       //   spanish_spain.8859      es_ES.ISO8859-1
  285.       //   # The following locale names are used in HPUX 9.x
  286.       //   american.iso88591       en_US.ISO8859-1
  287.       //   arabic.iso88596         ar_AA.ISO8859-6
  288.       //   bulgarian               bg_BG.ISO8859-5
  289.       //   c-french.iso88591       fr_CA.ISO8859-1
  290.       //   chinese-s               zh_CN.eucCN
  291.       //   chinese-t               zh_TW.eucTW
  292.       //   croatian                hr_HR.ISO8859-2
  293.       //   czech                   cs_CS.ISO8859-2
  294.       //   danish.iso88591         da_DK.ISO8859-1
  295.       //   dutch.iso88591          nl_BE.ISO8859-1
  296.       //   english.iso88591        en_EN.ISO8859-1
  297.       //   finnish.iso88591        fi_FI.ISO8859-1
  298.       //   french.iso88591         fr_CH.ISO8859-1
  299.       //   german.iso88591         de_CH.ISO8859-1
  300.       //   greek.iso88597          el_GR.ISO8859-7
  301.       //   hebrew.iso88598         iw_IL.ISO8859-8
  302.       //   hungarian               hu_HU.ISO8859-2
  303.       //   icelandic.iso88591      is_IS.ISO8859-1
  304.       //   italian.iso88591        it_IT.ISO8859-1
  305.       //   japanese                ja_JP.SJIS
  306.       //   japanese.euc            ja_JP.eucJP
  307.       //   korean                  ko_KR.eucKR
  308.       //   norwegian.iso88591      no_NO.ISO8859-1
  309.       //   polish                  pl_PL.ISO8859-2
  310.       //   portuguese.iso88591     pt_PT.ISO8859-1
  311.       //   rumanian                ro_RO.ISO8859-2
  312.       //   russian                 ru_SU.ISO8859-5
  313.       //   serbocroatian           sh_YU.ISO8859-2
  314.       //   slovak                  sk_SK.ISO8859-2
  315.       //   slovene                 sl_CS.ISO8859-2
  316.       //   spanish.iso88591        es_ES.ISO8859-1
  317.       //   swedish.iso88591        sv_SE.ISO8859-1
  318.       //   turkish.iso88599        tr_TR.ISO8859-9
  319.       //   # Solaris and SunOS have iso_8859_1 LC_CTYPES to augment LANG=C
  320.       //   iso_8859_1              en_US.ISO8859-1
  321.       //   # Microsoft Windows/NT 3.51 Japanese Edition
  322.       //   Korean_Korea.949        ko_KR.eucKR
  323.       //   Japanese_Japan.932      ja_JP.SJIS
  324.       //   # Other miscellaneous locale names
  325.       //   ISO8859-1               en_US.ISO8859-1
  326.       //   ISO-8859-1              en_US.ISO8859-1
  327.       //   japan                   ja_JP.eucJP
  328.       //   Japanese-EUC            ja_JP.eucJP
  329.       //
  330.       // GNU locale.alias:
  331.       //   czech                   cs_CZ.ISO-8859-2
  332.       //   danish                  da_DK.ISO-8859-1
  333.       //   dansk                   da_DK.ISO-8859-1
  334.       //   deutsch                 de_DE.ISO-8859-1
  335.       //   dutch                   nl_NL.ISO-8859-1
  336.       //   finnish                 fi_FI.ISO-8859-1
  337.       //   français                fr_FR.ISO-8859-1
  338.       //   french                  fr_FR.ISO-8859-1
  339.       //   german                  de_DE.ISO-8859-1
  340.       //   greek                   el_GR.ISO-8859-7
  341.       //   hebrew                  iw_IL.ISO-8859-8
  342.       //   hungarian               hu_HU.ISO-8859-2
  343.       //   icelandic               is_IS.ISO-8859-1
  344.       //   italian                 it_IT.ISO-8859-1
  345.       //   japanese                ja_JP.SJIS
  346.       //   japanese.euc            ja_JP.eucJP
  347.       //   norwegian               no_NO.ISO-8859-1
  348.       //   polish                  pl_PL.ISO-8859-2
  349.       //   portuguese              pt_PT.ISO-8859-1
  350.       //   romanian                ro_RO.ISO-8859-2
  351.       //   russian                 ru_RU.ISO-8859-5
  352.       //   slovak                  sk_SK.ISO-8859-2
  353.       //   slovene                 sl_CS.ISO-8859-2
  354.       //   spanish                 es_ES.ISO-8859-1
  355.       //   swedish                 sv_SE.ISO-8859-1
  356.       //   turkish                 tr_TR.ISO-8859-9
  357.       //
  358.       if (locale && *locale) {
  359.         // The most general syntax of a locale (not all optional parts
  360.         // recognized by all systems) is
  361.         // language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]]
  362.         // To retrieve the codeset, search the first dot. Stop searching when
  363.         // a '@' or '+' or ',' is encountered.
  364.         char* buf = (char*) malloc(strlen(locale)+1);
  365.         const char* codeset = NULL;
  366.         {
  367.           const char* cp = locale;
  368.           for (; *cp != '\0' && *cp != '@' && *cp != '+' && *cp != ','; cp++) {
  369.             if (*cp == '.') {
  370.               codeset = ++cp;
  371.               for (; *cp != '\0' && *cp != '@' && *cp != '+' && *cp != ','; cp++);
  372.               if (*cp != '\0') {
  373.                 size_t n = cp - codeset;
  374.                 memcpy(buf,codeset,n);
  375.                 buf[n] = '\0';
  376.                 codeset = buf;
  377.               }
  378.               break;
  379.             }
  380.           }
  381.         }
  382.         if (codeset) {
  383.           // Canonicalize the charset given after the dot.
  384.           if (   streq(codeset,"ISO8859-1")
  385.               || streq(codeset,"ISO_8859-1")
  386.               || streq(codeset,"iso88591")
  387.               || streq(codeset,"88591")
  388.               || streq(codeset,"88591.en")
  389.               || streq(codeset,"8859")
  390.               || streq(codeset,"8859.in")
  391.               || streq(codeset,"ascii")
  392.              )
  393.             locale_charset = "ISO-8859-1";
  394.           else
  395.           if (   streq(codeset,"ISO8859-2")
  396.               || streq(codeset,"ISO_8859-2")
  397.               || streq(codeset,"iso88592")
  398.              )
  399.             locale_charset = "ISO-8859-2";
  400.           else
  401.           if (   streq(codeset,"ISO8859-5")
  402.               || streq(codeset,"ISO_8859-5")
  403.               || streq(codeset,"iso88595")
  404.              )
  405.             locale_charset = "ISO-8859-5";
  406.           else
  407.           if (   streq(codeset,"ISO8859-6")
  408.               || streq(codeset,"ISO_8859-6")
  409.               || streq(codeset,"iso88596")
  410.              )
  411.             locale_charset = "ISO-8859-6";
  412.           else
  413.           if (   streq(codeset,"ISO8859-7")
  414.               || streq(codeset,"ISO_8859-7")
  415.               || streq(codeset,"iso88597")
  416.              )
  417.             locale_charset = "ISO-8859-7";
  418.           else
  419.           if (   streq(codeset,"ISO8859-8")
  420.               || streq(codeset,"iso88598")
  421.              )
  422.             locale_charset = "ISO-8859-8";
  423.           else
  424.           if (   streq(codeset,"ISO8859-9")
  425.               || streq(codeset,"ISO_8859-9")
  426.               || streq(codeset,"iso88599")
  427.              )
  428.             locale_charset = "ISO-8859-9";
  429.           else
  430.           if (streq(codeset,"KOI8-R"))
  431.             locale_charset = "KOI8-R";
  432.           else
  433.           if (streq(codeset,"KOI8-U"))
  434.             locale_charset = "KOI8-U";
  435.           else
  436.           if (   streq(codeset,"eucJP")
  437.               || streq(codeset,"ujis")
  438.               || streq(codeset,"AJEC")
  439.              )
  440.             locale_charset = "eucJP";
  441.           else
  442.           if (   streq(codeset,"JIS7")
  443.               || streq(codeset,"jis7")
  444.               || streq(codeset,"JIS")
  445.               || streq(codeset,"ISO-2022-JP")
  446.              )
  447.             locale_charset = "ISO-2022-JP"; /* was: "JIS7"; */
  448.           else
  449.           if (   streq(codeset,"SJIS")
  450.               || streq(codeset,"mscode")
  451.               || streq(codeset,"932")
  452.              )
  453.             locale_charset = "SJIS";
  454.           else
  455.           if (   streq(codeset,"eucKR")
  456.               || streq(codeset,"949")
  457.              )
  458.             locale_charset = "eucKR";
  459.           else
  460.           if (streq(codeset,"eucCN"))
  461.             locale_charset = "eucCN";
  462.           else
  463.           if (streq(codeset,"eucTW"))
  464.             locale_charset = "eucTW";
  465.           else
  466.           if (streq(codeset,"TACTIS"))
  467.             locale_charset = "TIS-620"; /* was: "TACTIS"; */
  468.           else
  469.           if (streq(codeset,"EUC") || streq(codeset,"euc")) {
  470.             if (locale[0]=='j' && locale[1]=='a')
  471.               locale_charset = "eucJP";
  472.             else if (locale[0]=='k' && locale[1]=='o')
  473.               locale_charset = "eucKR";
  474.             else if (locale[0]=='z' && locale[1]=='h' && locale[2]=='_') {
  475.               if (locale[3]=='C' && locale[4]=='N')
  476.                 locale_charset = "eucCN";
  477.               else if (locale[3]=='T' && locale[4]=='W')
  478.                 locale_charset = "eucTW";
  479.             }
  480.           }
  481.           else
  482.           // The following are CLISP extensions.
  483.           if (   streq(codeset,"UTF-8")
  484.               || streq(codeset,"utf8")
  485.              )
  486.             locale_charset = "UTF-8";
  487.         } else {
  488.           // No dot found. Choose a default, based on locale.
  489.           if (   streq(locale,"iso_8859_1")
  490.               || streq(locale,"ISO8859-1")
  491.               || streq(locale,"ISO-8859-1")
  492.              )
  493.             locale_charset = "ISO-8859-1";
  494.           else
  495.           if (0)
  496.             locale_charset = "ISO-8859-2";
  497.           else
  498.           if (0)
  499.             locale_charset = "ISO-8859-5";
  500.           else
  501.           if (0)
  502.             locale_charset = "ISO-8859-6";
  503.           else
  504.           if (0)
  505.             locale_charset = "ISO-8859-7";
  506.           else
  507.           if (0)
  508.             locale_charset = "ISO-8859-8";
  509.           else
  510.           if (0)
  511.             locale_charset = "ISO-8859-9";
  512.           else
  513.           if (0)
  514.             locale_charset = "KOI8-R";
  515.           else
  516.           if (0)
  517.             locale_charset = "KOI8-U";
  518.           else
  519.           if (0)
  520.             locale_charset = "eucJP";
  521.           else
  522.           if (0)
  523.             locale_charset = "ISO-2022-JP"; /* was: "JIS7"; */
  524.           else
  525.           if (0)
  526.             locale_charset = "SJIS";
  527.           else
  528.           if (0)
  529.             locale_charset = "eucKR";
  530.           else
  531.           if (streq(locale,"zh_CN") || streq(locale,"zh")
  532.              )
  533.             locale_charset = "eucCN";
  534.           else
  535.           if (streq(locale,"zh_TW")
  536.              )
  537.             locale_charset = "eucTW";
  538.           else
  539.           if (0)
  540.             locale_charset = "TIS-620"; /* was: "TACTIS"; */
  541.           else {
  542.             // Choose a default, based on the language only.
  543.             const char* underscore = strchr(locale,'_');
  544.             const char* lang;
  545.             if (underscore) {
  546.               size_t n = underscore - locale;
  547.               memcpy(buf,locale,n);
  548.               buf[n] = '\0';
  549.               lang = buf;
  550.             } else {
  551.               lang = locale;
  552.             }
  553.             if (   streq(lang,"af") || streq(lang,"afrikaans")
  554.                 || streq(lang,"ca") || streq(lang,"catalan")
  555.                 || streq(lang,"da") || streq(lang,"danish") || streq(lang,"dansk")
  556.                 || streq(lang,"de") || streq(lang,"german") || streq(lang,"deutsch")
  557.                 || streq(lang,"en") || streq(lang,"english")
  558.                 || streq(lang,"es") || streq(lang,"spanish")
  559. #ifndef ASCII_CHS
  560.                 || streq(lang,"espa\361ol") || streq(lang,"espa\303\261ol") //# español
  561. #endif
  562.                 || streq(lang,"eu") || streq(lang,"basque")
  563.                 || streq(lang,"fi") || streq(lang,"finnish")
  564.                 || streq(lang,"fo") || streq(lang,"faroese") || streq(lang,"faeroese")
  565.                 || streq(lang,"fr") || streq(lang,"french")
  566. #ifndef ASCII_CHS
  567.                                     || streq(lang,"fran\347ais") || streq(lang,"fran\303\247ais") //# français
  568. #endif
  569.                 || streq(lang,"ga") || streq(lang,"irish")
  570.                 || streq(lang,"gd") || streq(lang,"scottish")
  571.                 || streq(lang,"gl") || streq(lang,"galician")
  572.                 || streq(lang,"is") || streq(lang,"icelandic")
  573.                 || streq(lang,"it") || streq(lang,"italian")
  574.                 || streq(lang,"nl") || streq(lang,"dutch")
  575.                 || streq(lang,"no") || streq(lang,"norwegian")
  576.                 || streq(lang,"pt") || streq(lang,"portuguese")
  577.                 || streq(lang,"sv") || streq(lang,"swedish")
  578.                )
  579.               locale_charset = "ISO-8859-1";
  580.             else
  581.             if (   streq(lang,"cs") || streq(lang,"czech")
  582.                 || streq(lang,"cz")
  583.                 || streq(lang,"hr") || streq(lang,"croatian")
  584.                 || streq(lang,"hu") || streq(lang,"hungarian")
  585.                 || streq(lang,"pl") || streq(lang,"polish")
  586.                 || streq(lang,"ro") || streq(lang,"romanian") || streq(lang,"rumanian")
  587.                 || streq(lang,"sh") /* || streq(lang,"serbocroatian") ?? */
  588.                 || streq(lang,"sk") || streq(lang,"slovak")
  589.                 || streq(lang,"sl") || streq(lang,"slovene") || streq(lang,"slovenian")
  590.                 || streq(lang,"sq") || streq(lang,"albanian")
  591.                )
  592.               locale_charset = "ISO-8859-2";
  593.             else
  594.             if (   streq(lang,"eo") || streq(lang,"esperanto")
  595.                 || streq(lang,"mt") || streq(lang,"maltese")
  596.                )
  597.               locale_charset = "ISO-8859-3";
  598.             else
  599.             if (   streq(lang,"be") || streq(lang,"byelorussian")
  600.                 || streq(lang,"bg") || streq(lang,"bulgarian")
  601.                 || streq(lang,"mk") || streq(lang,"macedonian")
  602.                 || streq(lang,"sp")
  603.                 || streq(lang,"sr") || streq(lang,"serbian")
  604.                )
  605.               locale_charset = "ISO-8859-5";
  606.             else
  607.             if (streq(lang,"ar") || streq(lang,"arabic")
  608.                )
  609.               locale_charset = "ISO-8859-6";
  610.             else
  611.             if (streq(lang,"el") || streq(lang,"greek")
  612.                )
  613.               locale_charset = "ISO-8859-7";
  614.             else
  615.             if (streq(lang,"iw") || streq(lang,"he") || streq(lang,"hebrew")
  616.                )
  617.               locale_charset = "ISO-8859-8";
  618.             else
  619.             if (streq(lang,"tr") || streq(lang,"turkish")
  620.                )
  621.               locale_charset = "ISO-8859-9";
  622.             else
  623.             if (   streq(lang,"et") || streq(lang,"estonian")
  624.                 || streq(lang,"lt") || streq(lang,"lithuanian")
  625.                 || streq(lang,"lv") || streq(lang,"latvian")
  626.                )
  627.               locale_charset = "ISO-8859-10";
  628.             else
  629.             if (streq(lang,"ru") || streq(lang,"russian")
  630.                )
  631.               locale_charset = "KOI8-R";
  632.             else
  633.             if (streq(lang,"uk") || streq(lang,"ukrainian")
  634.                )
  635.               locale_charset = "KOI8-U";
  636.             else
  637.             if (   streq(lang,"ja")
  638.                 || streq(lang,"Jp")
  639.                 || streq(lang,"japan")
  640.                 || streq(lang,"Japanese-EUC")
  641.                )
  642.               locale_charset = "eucJP";
  643.             else
  644.             if (0)
  645.               locale_charset = "ISO-2022-JP"; /* was: "JIS7"; */
  646.             else
  647.             if (streq(lang,"japanese")
  648.                )
  649.               locale_charset = "SJIS";
  650.             else
  651.             if (streq(lang,"ko") || streq(lang,"korean")
  652.                )
  653.               locale_charset = "eucKR";
  654.             else
  655.             if (streq(lang,"chinese-s")
  656.                )
  657.               locale_charset = "eucCN";
  658.             else
  659.             if (streq(lang,"chinese-t")
  660.                )
  661.               locale_charset = "eucTW";
  662.             else
  663.             if (streq(lang,"th")
  664.                )
  665.               locale_charset = "TIS-620"; /* was: "TACTIS"; */
  666.             else {
  667.             }
  668.           }
  669.         }
  670.         free(buf);
  671.       }
  672.       return locale_charset;
  673.     }
  674.  
  675.